/**
 * Created by Administrator on 2017/4/25.
 */
import rt from 'angular-ui-router';
import html from './index.html';
import * as d3 from 'd3';
export default angular.module('husband.fridrlt',[rt])
  .config(['$stateProvider', function ($stateProvider) {
  $stateProvider.state('husband.fridRlt', {
    url: '/fridRlt',
    template:html
  });
}])
  .controller('rltController',["$scope","$http",function ($scope,$http) {
  $scope.title = 'rlt';
  var contentPath = 'http://192.168.1.108:8080/mmdb2';
  var ci1 = null,ci2 = null,ci3= null,allCi = null;
  var rlt = null;
  var rectR = 600,rectP = 30;
  var className = 'typeG';
  var pad,padTransfrom;
  var pathAll = {};

    $http.get('api/demoCi1').then(function (data) {
      ci1 = data.data.data.datas;
      typeSeparate();
    });
    $http.get('api/demoCi2').then(function (data) {
      ci2 = data.data.data.datas;
      typeSeparate();
    });
    $http.get('api/demoCi3').then(function (data) {
      ci3 = data.data.data.datas;
      typeSeparate();
    });
    $http.get('api/demoRlt').then(function (data) {
      rlt = data.data.data;
      nodeAndLine();
    });
    createSvg();
    //判断线的位置是否在node集合中
    function isInNodes (line,nodes) {
      var tflag = false;
      var sflag = false;
      for(var i = 0 ; i < nodes.length; i ++){
        if(line.startCi == nodes[i].id) {
          tflag = true
        }else if(line.endCi == nodes[i].id){
          sflag = true
        };
        if(tflag && sflag) {
          line.order = 1;
          return true
        }
      }
      return false
    }

    //将所有的node进行分类
    function typeSeparate() {
      if(ci1 && ci2 && ci3){
        var obj = {};
        allCi = {};
        for(var i = 0; i < ci1.length;i++) {
          allCi[ci1[i].id] = ci1[i]
        }
        for(var i = 0; i < ci2.length;i++) {
          allCi[ci2[i].id] = ci2[i]
        }
        for(var i = 0; i < ci3.length;i++) {
          allCi[ci3[i].id] = ci3[i]
        }
        obj[ci1[0].categoryId] = {};
        obj[ci1[0].categoryId].name = ci1[0].categoryName;
        obj[ci1[0].categoryId].node = [];
        obj[ci2[0].categoryId] = {};
        obj[ci2[0].categoryId].name = ci2[0].categoryName;
        obj[ci2[0].categoryId].node = [];
        obj[ci3[0].categoryId] = {};
        obj[ci3[0].categoryId].name = ci3[0].categoryName;
        obj[ci3[0].categoryId].node = [];
        obj[ci1[0].categoryId].node=obj[ci1[0].categoryId].node.concat(ci1);
        obj[ci2[0].categoryId].node=obj[ci2[0].categoryId].node.concat(ci2);
        obj[ci3[0].categoryId].node=obj[ci3[0].categoryId].node.concat(ci3);
        $scope.allCi = obj;
        nodeAndLine();
      }else {
        console.log('正在加载')
      }
    }


    //将所有的node和线处理
    function nodeAndLine() {
      if(rlt && allCi){
        //线的处理
        for(var i = 0 ; i <rlt.length;i++) {
          rlt[i].source = allCi[rlt[i].startCi];
          rlt[i].target = allCi[rlt[i].endCi];
          if( !rlt[i].target.sourceNode){
            rlt[i].target.sourceNode= {};
          }
          if( !rlt[i].source.targetNode){
            rlt[i].source.targetNode= {};
          }
          rlt[i].target.sourceNode[rlt[i].source.id] = 1;
          rlt[i].source.targetNode[rlt[i].target.id] = 1;

          rlt[i].target.num ? rlt[i].target.num++ : (rlt[i].target.num = 1);
        };
        var num = 0;
        for(var i in $scope.allCi) {
          pathAll[i] = false;
          $scope.allCi[i].topY = num * rectR;
          $scope.allCi[i].className = className+""+num;
          num++;
        }
      }
    }

    //创建svg元素
    function createSvg() {
      //将画布中的内容进行绘制
      pad = d3.select('.svgContainer')
        .append('svg')
        .style('position','relative')
        .attr('width','100%')
        .attr('height','100%')
        .append('g')
        .attr('class','allContainer')
      ;
      padTransfrom = d3.zoom().on('zoom',function(){ pad.attr('transform', d3.event.transform)});
      d3.select('svg').call(padTransfrom);
      var arrowMarker = pad.append("marker")
        .attr("id","arrow")
        .attr("markerUnits","strokeWidth")
        .attr("markerWidth",12)
        .attr("markerHeight",12)
        .attr("viewBox","0 0 24 24")
        .attr("refX",0)
        .attr("refY",12)
        .attr("orient","auto")
      ;
      var arrow_path = "M0,0 L0,24 L12,12 Z";
      // 定义箭头
      arrowMarker.append("path")
      .attr("d",arrow_path)
      .attr("fill","grey")
      ;
    }


    //过滤节点
    function filterNode(sels) {
      var sel = sels.datum();
      if(!sel.sourceNode && !sel.targetNode){
        d3.selectAll('.nodeG').classed('displayNode',false).style('opacity','0.1');
        d3.selectAll('.lineG').style('opacity','0.1');
        d3.selectAll('.displayLine').classed('displayLine',false);
        sels.classed('displayNode',true).style('opacity','1');
        console.log('error:节点没有关系');
        return
      }
      d3.selectAll('.nodeG').style('opacity','0.1');
      sels.style('opacity','1');
      d3.selectAll('.nodeG').each(function (d) {
       if(sel.targetNode && sel.targetNode[d.id]) {
          d3.select(this).classed('targetNode',true).style('opacity','1');
        }else if(sel.sourceNode && sel.sourceNode[d.id]){
          d3.select(this).classed('sourceNode',true).style('opacity','1');
        }
      });
      d3.selectAll('.lineG').each(function (d) {
        if(d.source.id == sel.id || d.target.id == sel.id){
          d3.select(this).style('opacity','1').select('path').classed('displayLine',true);
        }
        else {
          d3.select(this).style('opacity','0.1').select('path').classed('displayLine',false);
        }
      });

    }

    //回复节点
    function filterOver() {
      d3.selectAll('.nodeG')
      .classed('allNode',false)
      .classed('targetNode',false)
      .classed('sourceNode',false)
      .style('opacity','1');
      d3.selectAll('.lineG')
      .style('opacity','1');
    }
    //力学图绘制
    function forceDraw(className,obj) {
      padTransfrom.transform(d3.select('svg'),d3.zoomIdentity);
      var graph = pad.append('g')
      .datum(obj)
      .attr('class','forcePad')
      .classed(className,true)
      ;
      graph.append('text')
      .text(obj.name||'无')
      .attr('transform','translate('+obj.x+","+(obj.y+20)+')')
      ;
      graph.append('rect').attr('x',function (d) {
        return d.x
      }).attr('y',function (d) {
        return d.y
      })
      .attr('width',rectR - rectP)
      .attr('height',rectR- rectP)
      .attr('fill','none')
      .attr('stroke','black')
      ;
      for(var i = 0 ; i < obj.nodes.length; i ++) {
        obj.nodes[i].fx = undefined;
        obj.nodes[i].fy = undefined;
        obj.nodes[i].x = undefined;
        obj.nodes[i].y = undefined;
        obj.nodes[i].vx = undefined;
        obj.nodes[i].vy = undefined;
      }
      var force = objs.draw()(graph);
      var r = (rectR-rectP)/2;
      force.lineLength(100).size([r,r]).center([obj.x+ r,obj.y+r]).start( obj.nodes,obj.lines);


    }/*-----forceDraw--------*/

    //剩余连线的绘制
    function drawDline(pad) {
      var flag = 0;
      var num = 0;
      for(var i in pathAll) {
        num++;
        if(pathAll[i]){
          flag++;
        }
      }
      if(flag != num)return;

      var arr = [];
      for(var i = 0 ; i < rlt.length; i ++) {
        if(!rlt[i].order){
          arr.push(rlt[i])
        }
      };
      pad.selectAll('g.areaLine').remove();
      pad.selectAll('g.areaLine')
      .data(arr)
      .enter()
      .append('g')
      .attr('class','areaLine')
      .attr('opacity','0.1')
      .classed('lineG',true)
      .append('path')
      .attr('class','areaLine')
      .classed('linePath',true)
      .attr('stroke','black')
      .attr("marker-end","url(#arrow)")
      .attr('fill','none')
      ;
    }/*-----drawDline--------*/

    //更新连线
    function  updateLine() {
      var flag = 0;
      var num = 0;
      for(var i in pathAll) {
        num++;
        if(pathAll[i]){
          flag++;
        }
      }
      if(flag != num)return;
      d3.selectAll('path.areaLine').each(function () {
        d3.select(this).attr('d',function (d) {
          var dx = d.target.x - d.source.x,
          dy = d.target.y - d.source.y,
          dr = Math.sqrt(dx * dx + dy * dy);
          if(!dr){
            return 'M 0 0 L 0 0'
          }
          return ['M', d.source.x + d.source.r * dx / dr , d.source.y + d.source.r * dy / dr ,
            'L', d.target.x - (d.target.r + 4) * dx / dr , d.target.y - (d.target.r + 4) * dy / dr].join(' ');
        })
      });
    }/*-----drawDline--------*/


    //力学图对象
    var objs = {};
    objs.draw = function () {
      var pad = null;
      var graph = null;
      var lineLength = 200;
      var lines = null,width = 380,height = 380,force = null,r = 10;
      var centerX = 0,centerY = 0;
      function _force(contain) {
        pad = contain ? contain : d3.select('svg');
        _force.init();
        graph = pad;
        return _force;
      }
      /*一些初始化的东西*/
      _force.init = function () {
        // var arrowMarker = pad.append("marker")
        // .attr("id","arrow")
        // .attr("markerUnits","strokeWidth")
        // .attr("markerWidth",12)
        // .attr("markerHeight",12)
        // .attr("viewBox","0 0 24 24")
        // .attr("refX",0)
        // .attr("refY",12)
        // .attr("orient","auto")
        // ;
        // var arrow_path = "M0,0 L0,24 L12,12 Z";
        // // 定义箭头
        // arrowMarker.append("path")
        // .attr("d",arrow_path)
        // .attr("fill","grey")
        // ;
      };
      /*
       * 进行绘制的容器缩放事件（参数：d3元素）
       *

       /*
       * 绘制线的距离改变
       * */
      _force.lineLength = function (length) {
        lineLength = length;
        return this
      };
      _force.changeR = function (nodeR) {
        r = nodeR;
        return this
      };
      /*
       * 绘制的区域参数（[宽,高]）
       * */
      _force.size = function (arr) {
        width = arr[0];
        height = arr[1];
        return this
      };
      /*
       * 绘制的区域坐标（[x,y]）
       * */
      _force.center = function (arr) {
        centerX = arr[0];
        centerY = arr[1];
        return this
      };

      /*
       * 进行线数据的处理(进行传入所有的lines数据)
       * */
      _force.lines = function (lineData) {
        lines = d3.forceLink(lineData)
        .id(function (d) {
          return d.id
        })
        .distance(function (d) {
          return lineLength + d.target.num * 5;
        })
        .strength(0.01)
        ;
        _force.drawLines(lineData);
      };
      /*
       * 进行线数据的处理(进行传入所有的nodes的数据)
       * */
      _force.nodes = function (nodeData) {
        var maxZone;
        if(width > height){
          maxZone = height
        }else {
          maxZone = width
        }
        force = d3.forceSimulation(nodeData)
        .force("link", lines)
        .force("charge", d3.forceManyBody().strength(-300).theta(1).distanceMax(maxZone/2))
        .force("center", d3.forceCenter(centerX, centerY))
        ;
        force.alpha(0.1).alphaTarget(0.1).velocityDecay(0.1);
        _force.drawNodes(nodeData);
        force.on('tick',function () {
          var maxX = centerX + maxZone/2;
          var minX = centerX - maxZone/2;
          var maxY = centerY + maxZone/2;
          var minY = centerY - maxZone/2;
          graph.selectAll('.nodeG').attr('transform',function (d) {
            if(d.x > maxX){
              d.x = maxX
            }else if(d.x < minX) {
              d.x = minX
            }
            if(d.y > maxY){
              d.y = maxY
            }else if(d.x < minY) {
              d.y = minY
            };

            return 'translate(' + d.x + ',' + d.y + ')';
          })
          ;
          _force.updateLine();
        });
      };


      /*
       * 更新连线
       * */
      _force.updateLine = function (sel) {
        updateLine();
        if(!sel){
          graph.selectAll('.force_line').attr('d',function (d) {
            var dx = d.target.x - d.source.x,
            dy = d.target.y - d.source.y,
            dr = Math.sqrt(dx * dx + dy * dy);
            return ['M', d.source.x + d.source.r * dx / dr , d.source.y + d.source.r * dy / dr ,
              'L', d.target.x - (d.target.r + 4) * dx / dr , d.target.y - (d.target.r + 4) * dy / dr].join(' ');
          });
          force.alphaTarget(0);
        }else {
          sel.attr('d',function (d) {
            var dx = d.target.x - d.source.x,
            dy = d.target.y - d.source.y,
            dr = Math.sqrt(dx * dx + dy * dy);
            return ['M', d.source.x + d.source.r * dx / dr , d.source.y + d.source.r * dy / dr ,
              'L', d.target.x - (d.target.r + 4) * dx / dr , d.target.y - (d.target.r + 4) * dy / dr].join(' ');
          });
        }

      };

      /*
       * 过滤连线并更新
       * */
      _force.filterLine = function (id) {
        var line = graph.selectAll('.force_line').filter(function (d) {
          return (d.target.id == id || d.source.id == id)
        });
        return line;
      };
      /*
       * 进行绘图
       * */
      _force.drawLines = function (lines) {
        var ele = graph.selectAll('g.lineG').data(lines).enter().append('g').attr('class','lineG');
        ele.append('path').attr('class','force_line').classed('linePath',true).attr('stroke','black').attr("marker-end","url(#arrow)").attr('fill','none');
      };
      _force.drawNodes = function (nodes) {
        function dragstart(d) {
          if (!d3.event.active) force.stop();
          if(!d.fx){
            d.fx = d.x;   d.fy = d.y;
          }
        }
        function dragging(d) {
          d.x += d3.event.dx;d.y += d3.event.dy;
          d.fx += d3.event.dx;  d.fy += d3.event.dy;
          d3.select(this).attr('transform',function () {
            return 'translate('+ d.fx +','+ d.fy +')';
          });
          var sel = _force.filterLine(d.id);
          _force.updateLine(sel);
        }
        function dragged(d) {
          // if (!d3.event.active) force.alphaTarget(0);
          // d.fx = d3.event.x;  d.fy = d3.event.y;
        };
        var dragEvent = d3.drag().on('start',dragstart).on('drag',dragging).on('end',dragged);
        var ele = graph.selectAll('g.nodeG').data(nodes).enter().append('g').attr('class','nodeG');
        //添加球
        ele.append('rect')
        .attr('class','force_circle')
        .attr('x',function (d) {
          if(d.num){
            d.r = d.num * 2 +  r;
          }else {
            d.r = r;
          }
          return -d.r* Math.sqrt(0.5)
        })
        .attr('y',function (d) {
          return -d.r* Math.sqrt(0.5)
        })
        .attr('height',function (d) {
          return 2*d.r* Math.sqrt(0.5)
        })
        .attr('width',function (d) {
          return 2*d.r* Math.sqrt(0.5)

        })
        .attr('fill',function (d) {
          return d.classColor || '#3fa8df'
        })
        .style('opacity',0)
        ;

        ele.append('image')
        .attr('class','background')
        .attr('xlink:href',function (d) {
          return contentPath + d.icon
        })
        .attr('width',function (d) {
          return 2*d.r* Math.sqrt(0.5)
        })
        .attr('height',function (d) {
          return 2*d.r* Math.sqrt(0.5)
        })
        .attr('transform',function (d) {
          return "translate("+  (-d.r* Math.sqrt(0.5)) + ", "+ (-d.r* Math.sqrt(0.5)) +")"
        })
        ;
        ele.append('text').text(function (d) {
          if(d.name.length > 5){
            return d.name.substr(0, 5) +"..."
          }
          return d.name
        })
        .attr('text-anchor','middle')
        ;
        ele.append('title').text(function (d) {
          return d.name
        });
        ele.on('mouseenter',function () {
          // filterNode(d3.select(this));
        })
        .on('mouseleave',function () {
          // filterOver();
        });
        ele.call(dragEvent);
      };

      /*
       * 进行数据的处理(进行传入所有的lines数据,还有线的长度)
       * */
      _force.start = function (nodeData,lineData) {
        _force.init();
        _force.lines(lineData);
        _force.nodes(nodeData);
        setTimeout(_force.end,5000);
      };
      /*
       * 进行force终止
       */
      _force.end = function () {
        force.stop();
        return _force;
      };

      return _force
    };/*-----力学图对象--------*/



  $scope.typeChange = function (type,data) {
    var className = '.' + data.className;
    pad.selectAll(className).remove();
     // 对分类进行分别绘图
    var obj = {};
    var ci = data.node;
    var number = data.topY;
    //将节点分组
    for (var i = 0; i < ci.length; i++) {
      if(!ci[i].data[type]){
        ci[i].data[type] = '无'
      }
      if (!obj[ci[i].data[type]]) {
        obj[ci[i].data[type]] = {};
        obj[ci[i].data[type]].nodes = [];
        obj[ci[i].data[type]].topY = number;
        obj[ci[i].data[type]].name = ci[i].data[type];
        obj[ci[i].data[type]].lines = [];
      }
      obj[ci[i].data[type]].nodes.push(ci[i]);
    }
    //根据节点放入连线,对节点进行初始话的x,y
    var num = 0;
    for(var i in obj) {
      obj[i].x = num * rectR;
      num++;
      obj[i].y = obj[i].topY;
      for(var x = 0 ; x< rlt.length;x++ ) {
        if(isInNodes(rlt[x],obj[i].nodes))obj[i].lines.push(rlt[x]);
      }
    };
    //进行绘制
    for(var i in obj) {
      forceDraw(data.className,obj[i])
    }
    pathAll[data.node[0].categoryId] = true;
    drawDline(pad);
    d3.selectAll('.nodeG').on('mouseenter',function () {
      filterNode(d3.select(this))
    });

    };














}]);